#!/usr/bin/env python
#
# This is a port of classical passgen (provided by jxself) into the python 
# language.
#
# Usage: passgen.py [service-specific string]
#
# Use this program if you do not have access to a graphical environment or if
# you can't install PyGTK. Otherwise, run main.py
# 
#    Copyright (C) 2016 - kzimmermann <https://quitter.se/kzimmermann>
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

import sys
import base64 as b64
import hashlib
from getpass import getpass

#---- Standard configuration variables:

seclevel = 7 # how many times tokens are hashed

#---- Functions:

def secure_hash(token):
    """
    Hashes multiple times a given string so as to provide something that should
    not be easy to reverse. Standardized as seven times, but feel free to 
    change it to as much as your own paranoia needs.

    Returns a SHA-256 hash.
    """
    temp = str(token)
    for i in xrange(seclevel):
        temp = hashlib.sha256(temp).hexdigest()
    return temp

def generate(salt, string):
    """
    Generates a 32-char long password based on algorithm v1 (hash then encode).
    Arguments are a password seed (called a salt) and a service-specific string
    so all passwords generated will be different.

    The 32 characters are sampled from a different position depending on the
    salt used. This should always work provided that the salt isn't too long.
    """

    # So that the sampling is not that obvious ;)
    start = len("%s%s" % (salt, string)) 

    temp = secure_hash("%s%s" % (salt, string))
    return b64.b64encode(temp)[start:start+32]

def main():
    """
    Main interaction when module has not been imported
    """
    while True:
        seed = getpass("Enter your salt: ")
        seed_confirm = getpass("Confirm: ") 
        
        if seed == seed_confirm:
            break
        else:
            print "Salts don't match. Try again."

    if len(sys.argv) == 1:
        string = raw_input("Enter your string: ")
    elif len(sys.argv) == 2:
        string = sys.argv[1]

    print generate(seed, string)
    raw_input("Copy this, clear your clipboard and press Enter. ")

    # Clear the screen to make difficult (but not impossible) to view the
    # password again.

    for i in xrange(500):
        print "\n\n\n\n\n"



if __name__ == "__main__":
    main()
    sys.exit(0)
